<!DOCTYPE html>
<html>
<head>
<title>Stringifying a PushSubscription object includes all object members</title>
<link rel="manifest" href="resources/push_manifest.json">
<script src="resources/push-constants.js"></script>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../serviceworker/resources/test-helpers.js"></script>
</head>
<body>
<script>
// Converts an ArrayBuffer to a base64url encoded string.
function ArrayBufferToBase64UrlEncodedString(buffer) {
    var base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)));
    return base64.replace(/\//g, '_').replace(/\+/g, '-').replace(/=$/, '');
}

async_test(function(test) {
    var workerUrl = 'resources/empty_worker.js';
    var workerScope = 'resources/scope/' + location.pathname;
    var swRegistration;
    service_worker_unregister_and_register(test, workerUrl, workerScope)
        .then(test.step_func(serviceWorkerRegistration => {
            swRegistration = serviceWorkerRegistration;
            return wait_for_state(test, swRegistration.installing, 'activated');
        }))
        .then(test.step_func(() => {
            // If running manually, grant permission when prompted.
            if (window.testRunner)
                testRunner.setPermission('push-messaging', 'granted', location.origin, location.origin);
            return swRegistration.pushManager.subscribe({ userVisibleOnly: true });
        }))
        .then(test.step_func(pushSubscription => {
            var reflectedObject = JSON.parse(JSON.stringify(pushSubscription));

            assert_own_property(reflectedObject, 'endpoint');
            assert_equals(reflectedObject.endpoint, pushSubscription.endpoint);

            // Expiration time should be in the expected window
            assert_own_property(reflectedObject, 'expirationTime');
            assert_true(typeof pushSubscription.expirationTime === 'number');
            assert_approx_equals(pushSubscription.expirationTime, Date.now() +
                                 EXPIRATION_WINDOW, EXPIRATION_TIME_TOLERANCE,
                                 `Expiration time should be in expected window: ${EXPIRATION_TIME_TOLERANCE} ms`);
            assert_own_property(reflectedObject, 'keys');
            assert_own_property(reflectedObject.keys, 'p256dh');
            assert_own_property(reflectedObject.keys, 'auth');

            var key = ArrayBufferToBase64UrlEncodedString(pushSubscription.getKey('p256dh')),
                auth = ArrayBufferToBase64UrlEncodedString(pushSubscription.getKey('auth'));

            assert_equals(reflectedObject.keys.p256dh, key);
            assert_equals(reflectedObject.keys.auth, auth);

            return service_worker_unregister_and_done(test, workerScope);
        }))
        .catch(unreached_rejection(test));
}, 'Stringifying a PushSubscription object includes all object members');
</script>
</body>
</html>
